package com.xuecheng.media.service.impl;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.Update;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.media.model.dto.MediaAuditDTO;
import com.xuecheng.api.media.model.dto.MediaDTO;
import com.xuecheng.api.media.model.vo.MediaAuditVO;
import com.xuecheng.api.media.model.vo.MediaVO;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.enums.common.AuditEnum;
import com.xuecheng.common.enums.common.ResourceTypeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.feign.Client.ContentFeignClient;
import com.xuecheng.feign.config.FeignConfig;
import com.xuecheng.feign.pojo.TeachplanMedia;
import com.xuecheng.media.common.constant.MediaErrorCode;
import com.xuecheng.media.common.utils.AliyunVODUtil;
import com.xuecheng.media.controller.MediaAuditController;
import com.xuecheng.media.controller.MediaController;
import com.xuecheng.media.convert.MediaConvert;

import com.xuecheng.media.entity.Media;
import com.xuecheng.media.mapper.MediaMapper;
import com.xuecheng.media.service.MediaService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.xml.SimpleSaxErrorHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 媒资信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {
 /*
    * 业务分析：
    *   1.判断关键
    *       companyid  filename  fileid(videoId)
    *   2.给信息数据赋值默认值   // 默认是未审核的
    *       auditStatus：未审核
    *
    *   3.保存信息
    *   4.将数据库最新数据返回
    *
    * */
    @Transactional
    public MediaDTO createMedia(MediaDTO dto) {
        // 判断关键数据
        if(ObjectUtils.isEmpty(dto.getCompanyId())||
        ObjectUtils.isEmpty(dto.getFilename())||
                ObjectUtils.isEmpty(dto.getFileId()) ){
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        // 业务
        dto.setAuditStatus(AuditEnum.AUDIT_UNPAST_STATUS.getCode());
        if(dto.getType().equals(ResourceTypeEnum.VIDEO)){
            String playUrl = this.getAliyunVodPlayUrl(dto.getFileId());
            dto.setUrl(playUrl);
            // 放在redis中。。。
        }

//        3.保存信息
        Media entity = MediaConvert.INSTANCE.dto2entity(dto);
        boolean save = this.save(entity);
        if(!save){
            ExceptionCast.cast(MediaErrorCode.E_140001);
        }

//        4.将数据库最新数据返回
        Media media = this.getById(entity.getId());

        return MediaConvert.INSTANCE.po2dto(media);

    }

    /**
     *  TODO 返回类型未定义
     * @param params  分页参数
     * @param vo  查询条件 key  filename,type
     * @param companyId  公司id 判断是否是同一家机构
     * @return
     */
    @Override
    public PageVO<MediaDTO> queryMedia(PageRequestParams params, MediaVO vo, Long companyId) {
        /**
         *  1. 是否开启业务支持 0
         *  2， 判断关键数据
         *  3， 判断业务数据  filename,type
         *  4. 根据条件查询数据库
         *  5. 封装对象
         */

//        2， 判断关键数据
        if(ObjectUtils.isEmpty(params.getPageNo())){
            params.setPageNo(1L);
        }
        if(ObjectUtils.isEmpty(params.getPageSize())){
            params.setPageSize(20);
        }

        if(ObjectUtils.isEmpty(companyId)){
            ExceptionCast.cast(MediaErrorCode.E_140010);
        }

//        3， 判断业务数据
        // 都不存在执行无条件查询
        Page<Media> page = new Page<>( params.getPageNo(),params.getPageSize());
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper=null;
//        4. 根据条件查询数据
        if(!ObjectUtils.isEmpty(vo.getFilename())){
            queryWrapper.like(Media::getFilename,vo.getFilename());
        }
        if(!ObjectUtils.isEmpty(vo.getType())){
            queryWrapper.eq(Media::getFilename,vo.getType());
        }



        // 查询未被删除的
            queryWrapper.eq(Media::getStatus,"1");
        // 查自己公司的
        if(!companyId.equals(MediaAuditController.OPERATION_FLAG)){
            queryWrapper.eq(Media::getCompanyId,companyId);
        }



        Page<Media> mediaPage = this.page(page, queryWrapper);
        List<Media> records = mediaPage.getRecords();
        long total = mediaPage.getTotal();
        if(CollectionUtils.isEmpty(records)){
            records=new ArrayList<Media>();
        }


        List<MediaDTO> dtos=MediaConvert.INSTANCE.vos2dtos(records);

//       Page<MediaDTO> mediaDTOPage =MediaConvert.INSTANCE.Medias4MediaDTOs(mediaPage);
//        5. 封装对象
        PageVO<MediaDTO> mediaDTOS = new PageVO<>();
        mediaDTOS.setItems(dtos);
        mediaDTOS.setCounts(total);
        mediaDTOS.setPage(Integer.parseInt(params.getPageNo()+""));
        mediaDTOS.setPageSize(Integer.parseInt(page.getSize()+""));
        return mediaDTOS;
    }


    @Autowired
    private ContentFeignClient feignClient;

    @Override
    @Transactional
    public void removeMedia(int mediaId, Long companyId) {
        /**
         *  0. 是否开启事务i  是
         *  1. 判断关键数据   判断 mediaid companyid 是否为空
         *  2. 判断业务数据
         *        判断 media 是否存在
         *        是否是同一家机构
         *        是否被删除
         *        是否是审核未通过或者未提交状态
         *
         *  3. 业务操作
         *        删除
         *        判断删除操作的成功
         *
         */
        // 1.判断关键数据   判断 mediaid companyid 是否为空
        if(ObjectUtils.isEmpty(mediaId)||ObjectUtils.isEmpty(companyId)){
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2. 判断业务数据
        //   判断 media 是否存在
        Media media = this.getById(mediaId);
        if(ObjectUtils.isEmpty(media)){
            ExceptionCast.cast(MediaErrorCode.E_140005);
        }

        if (!media.getCompanyId().equals(companyId)){
            ExceptionCast.cast(MediaErrorCode.E_140008);
        }
        if(media.getStatus().equals("0")){
            ExceptionCast.cast(MediaErrorCode.E_140002);
        }

        if(media.getAuditStatus().equals(AuditEnum.AUDIT_PASTED_STATUS.getCode())){
            ExceptionCast.cast(MediaErrorCode.E_140009);
        }
        //   是否是同一家机构
        //   是否被删除
        //   是否是审核未通过或者未提交状态
        //   是否有课程计划，如果绑定了课程计划就不能删除
//        TeachplanMedia teachplanMedia = feignClient.queryTeachplanMediaById((long) mediaId);
//        if(!ObjectUtils.isEmpty(teachplanMedia)){  // 如果没绑定课程计划可以删除
//            ExceptionCast.cast(MediaErrorCode.E_140003);
//        }
        //        3. 业务操作
//                删除
//        判断删除操作的成功

        LambdaUpdateWrapper<Media> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Media::getStatus,"0");
        updateWrapper.eq(Media::getId,mediaId);

        boolean update = this.update(updateWrapper);

        if(!update){
            ExceptionCast.cast(MediaErrorCode.E_140002);
        }
        //阿里云的媒资也要删除


    }




    @Value("${aliyun.region}")
    private  String region;
    @Value("${aliyun.accessKeyId}")
    private  String accessKeyId;
    @Value("${aliyun.accessKeySecret}")
    private  String accessKeySecret;

    /**
     * 获得阿里云视频播放地址
     * @param fileId
     * @return
     */
    private String getAliyunVodPlayUrl(String fileId) {

        String playURL = null;
        try {
            DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);

            GetPlayInfoResponse playInfo = AliyunVODUtil.getPlayInfo(client, fileId);

            List<GetPlayInfoResponse.PlayInfo> playInfoList = playInfo.getPlayInfoList();

            if (CollectionUtils.isEmpty(playInfoList)) {
                ExceptionCast.cast(MediaErrorCode.setErrorCode(999999));
            }

            // 默认获得第一个播放地址
            playURL = playInfoList.get(0).getPlayURL();
        } catch (Exception e) {
            log.error(MediaErrorCode.E_140012.getDesc()+" : {}",e.getMessage());
            ExceptionCast.cast(MediaErrorCode.E_140012);
        }

        return playURL;
    }


    @Override
    @Transactional
    public void approveMedia(MediaAuditDTO dto) {
        /**
         *   0. 是否开启事务
         *   1. 判断关键数据
         *   2.  判断业务数据
         *   3.  修改审核信息  检查修改状态
         *
         */

//        1. 判断关键数据    审核状态和id 不能为空 否则找不到这个数据
          if(StringUtil.isBlank(dto.getAuditStatus())||
             ObjectUtils.isEmpty(dto.getId())||
            ObjectUtils.isEmpty(dto.getAuditMind())){
              ExceptionCast.cast(CommonErrorCode.E_100101);
          }
//        2.  判断业务数据
          Media media = this.getById(dto.getId());
          // 是不是存在
          if(ObjectUtils.isEmpty(media)){
              ExceptionCast.cast(MediaErrorCode.E_140005);
          }
           // 是不是 审核通过
          if(media.getAuditStatus().equals(AuditEnum.AUDIT_PASTED_STATUS)){
              ExceptionCast.cast(MediaErrorCode.E_140016);
          }
          // 是不是被删除
          if(media.getStatus().equals("0")){
              ExceptionCast.cast(MediaErrorCode.E_140005);
          }

//        3.  修改审核信息  检查修改状态
        LambdaUpdateWrapper<Media> updateWrapper = new LambdaUpdateWrapper<>();
          updateWrapper.set(Media::getAuditStatus,dto.getAuditStatus());

              updateWrapper.set(Media::getAuditMind,dto.getAuditMind());

          updateWrapper.eq(Media::getId,dto.getId());
        boolean update = this.update(updateWrapper);
        if(!update){
            ExceptionCast.cast(MediaErrorCode.E_140017);
        }

    }



    @Override
    public String mediaPriview(int mediaId,Long companyId) {
        /**
         *  0. 是否开事务
         *  1. 判断关键数据
         *  2。判断业务数据
         *  3. 拿到url
         *  4. 返回
         */
        if(ObjectUtils.isEmpty(mediaId)||ObjectUtils.isEmpty(companyId)){
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        // 2。判断业务数据
                 // 媒资信息
                     // 是否存在
                     // 是否是同一家机构
                     // 是否被删除
        Media media = this.getById(mediaId);

        if(ObjectUtils.isEmpty(media)){
            ExceptionCast.cast(MediaErrorCode.E_140005);
        }
        // 不是管理员
        if(!companyId.equals(MediaAuditController.OPERATION_FLAG)){
            // 不是同一个公司
            if(!companyId.equals(media.getCompanyId())){
                ExceptionCast.cast(MediaErrorCode.E_140016);
            }
        }
        // 没被删除
        if(media.getStatus().equals("0")){
            ExceptionCast.cast(MediaErrorCode.E_140005);
        }

        return media.getUrl();
    }
}